package com.kite.music;

// 该类负责处理文件相关

import android.app.Activity;
import android.content.Context;
import android.os.Environment;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import com.kite.enums.enFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.ReentrantLock;
import org.json.JSONObject;
import org.json.JSONArray;


public class FileUtil {
    private WebView webview;
    private Activity activity;
    private Context context;
    public  File appPrivateDir = null;
    public  File appPublicDir =  null;
    private final ReentrantLock fileLock = new ReentrantLock();

    public FileUtil(WebView webview, Activity activity, Context context){
        this.webview = webview;
        this.activity = activity;
        this.context = context;
        this.appPrivateDir = context.getFilesDir();
        this.appPublicDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
        ensureDirectoriesExist();
    }

    // 确保目录存在
    public void ensureDirectoriesExist() {
        if (appPrivateDir != null && !appPrivateDir.exists()) {
            appPrivateDir.mkdirs();
        }
        if (appPublicDir != null && !appPublicDir.exists()) {
            appPublicDir.mkdirs();
        }
    }

    // 创建文件 - 重构版本，返回文件路径而不是File对象
    @JavascriptInterface
    public String createFile(String directory, String fileName, String suffix) {
        return executeFileOperation(() -> {
            // 参数验证
            if (fileName == null || fileName.trim().isEmpty()) {
                return createErrorResponse("文件名不能为空");
            }
            // 确定目标目录
            File targetDir;
            if ("internal".equals(directory) || "INNER_DIR".equals(directory)) {
                targetDir = this.appPrivateDir;
            } else if ("external".equals(directory) || "OUTER_DIR".equals(directory)) {
                targetDir = this.appPublicDir;
            } else {
                return createErrorResponse("无效的目录类型: " + directory);
            }

            if (targetDir == null) {
                return createErrorResponse("目录未初始化或不可用");
            }

            // 创建文件
            File file = new File(targetDir, fileName + suffix);

            // 如果文件已存在，直接返回路径
            if (file.exists()) {
                return createSuccessResponse(file.getAbsolutePath());
            }

            // 确保父目录存在
            File parentDir = file.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                if (!parentDir.mkdirs()) {
                    return createErrorResponse("无法创建父目录: " + parentDir.getAbsolutePath());
                }
            }

            // 创建文件
            try {
                if (file.createNewFile()) {
                    return createSuccessResponse(file.getAbsolutePath());
                } else {
                    return createErrorResponse("文件创建失败: " + file.getAbsolutePath());
                }
            } catch (IOException e) {
                return createErrorResponse("文件创建异常: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public String createF(String directory, String name, String suffix) {
        return createFile(directory, name, suffix);
    }

    // 写入数据 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String writeTextToFile(String filePath, String content) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);

            // 确保父目录存在
            File parentDir = file.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                if (!parentDir.mkdirs()) {
                    return createErrorResponse("无法创建父目录: " + parentDir.getAbsolutePath());
                }
            }

            try (BufferedWriter bufferedWriter = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
                bufferedWriter.write(content);
                bufferedWriter.flush();
                return createSuccessResponse("写入成功");
            } catch (IOException e) {
                return createErrorResponse("写入文件失败: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean writeText(String filePath, String text) {
        try {
            String result = writeTextToFile(filePath, text);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 追加数据 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String appendTextToFile(String filePath, String content) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);

            // 确保父目录存在
            File parentDir = file.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                if (!parentDir.mkdirs()) {
                    return createErrorResponse("无法创建父目录: " + parentDir.getAbsolutePath());
                }
            }

            try (BufferedWriter bufferedWriter = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(file, true), StandardCharsets.UTF_8))) {
                bufferedWriter.write(content);
                bufferedWriter.newLine();
                bufferedWriter.flush();
                return createSuccessResponse("追加成功");
            } catch (IOException e) {
                return createErrorResponse("追加文件失败: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean appendText(String filePath, String text) {
        try {
            String result = appendTextToFile(filePath, text);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 读取数据 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String readTextFromFile(String filePath) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);

            if (!file.exists()) {
                return createErrorResponse("文件不存在: " + filePath);
            }

            if (!file.canRead()) {
                return createErrorResponse("无法读取文件: " + filePath);
            }

            StringBuilder text = new StringBuilder();
            try (BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
                char[] buffer = new char[8192];
                int charsRead;
                while ((charsRead = bufferedReader.read(buffer)) != -1) {
                    text.append(buffer, 0, charsRead);
                }
                return createSuccessResponse(text.toString());
            } catch (IOException e) {
                return createErrorResponse("读取文件失败: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public String readText(String filePath) {
        try {
            String result = readTextFromFile(filePath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success") ?
                response.getString("data") : "";
        } catch (Exception e) {
            return "";
        }
    }

    // 从assets读取资源文件
    @JavascriptInterface
    public String readAssetFile(String assetPath) {
        return executeFileOperation(() -> {
            if (assetPath == null || assetPath.trim().isEmpty()) {
                return createErrorResponse("资源路径不能为空");
            }

            try {
                StringBuilder text = new StringBuilder();
                try (InputStream inputStream = context.getAssets().open(assetPath);
                     BufferedReader reader = new BufferedReader(
                         new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {

                    char[] buffer = new char[8192];
                    int charsRead;
                    while ((charsRead = reader.read(buffer)) != -1) {
                        text.append(buffer, 0, charsRead);
                    }
                }
                return createSuccessResponse(text.toString());
            } catch (IOException e) {
                return createErrorResponse("读取资源文件失败: " + e.getMessage());
            }
        });
    }

    // 删除文件 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String deleteFileByPath(String filePath) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);

            if (!file.exists()) {
                return createErrorResponse("文件不存在: " + filePath);
            }

            try {
                if (file.delete()) {
                    return createSuccessResponse("删除成功");
                } else {
                    return createErrorResponse("删除失败，可能文件被占用");
                }
            } catch (SecurityException e) {
                return createErrorResponse("删除失败，没有足够权限: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean deleteFile(String filePath) {
        try {
            String result = deleteFileByPath(filePath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 检查文件是否存在 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String fileExistsByPath(String filePath) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);
            boolean exists = file.exists();
            return createSuccessResponse(String.valueOf(exists));
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean fileExists(String filePath) {
        try {
            String result = fileExistsByPath(filePath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success") ?
                Boolean.parseBoolean(response.getString("data")) : false;
        } catch (Exception e) {
            return false;
        }
    }

    // 获取文件大小 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String getFileSizeByPath(String filePath) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            File file = new File(filePath);

            if (!file.exists()) {
                return createErrorResponse("文件不存在: " + filePath);
            }

            if (!file.isFile()) {
                return createErrorResponse("指定路径不是文件: " + filePath);
            }

            long size = file.length();
            return createSuccessResponse(String.valueOf(size));
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public long getFileSize(String filePath) {
        try {
            String result = getFileSizeByPath(filePath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success") ?
                Long.parseLong(response.getString("data")) : 0;
        } catch (Exception e) {
            return 0;
        }
    }

    // 重命名文件 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String renameFileByPath(String filePath, String newName) {
        return executeFileOperation(() -> {
            if (filePath == null || filePath.trim().isEmpty()) {
                return createErrorResponse("文件路径不能为空");
            }

            if (newName == null || newName.trim().isEmpty()) {
                return createErrorResponse("新文件名不能为空");
            }

            File file = new File(filePath);

            if (!file.exists()) {
                return createErrorResponse("文件不存在: " + filePath);
            }

            File newFile = new File(file.getParent(), newName.trim());

            try {
                if (file.renameTo(newFile)) {
                    return createSuccessResponse("重命名成功");
                } else {
                    return createErrorResponse("重命名失败，可能目标文件已存在");
                }
            } catch (SecurityException e) {
                return createErrorResponse("重命名失败，没有足够权限: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean renameFile(String filePath, String newName) {
        try {
            String result = renameFileByPath(filePath, newName);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 复制文件 - 重构版本，接受文件路径而不是File对象
    @JavascriptInterface
    public String copyFileByPath(String sourcePath, String destPath) {
        return executeFileOperation(() -> {
            if (sourcePath == null || sourcePath.trim().isEmpty()) {
                return createErrorResponse("源文件路径不能为空");
            }

            if (destPath == null || destPath.trim().isEmpty()) {
                return createErrorResponse("目标文件路径不能为空");
            }

            File sourceFile = new File(sourcePath);
            File destFile = new File(destPath);

            if (!sourceFile.exists()) {
                return createErrorResponse("源文件不存在: " + sourcePath);
            }

            if (!sourceFile.isFile()) {
                return createErrorResponse("源路径不是文件: " + sourcePath);
            }

            // 确保目标目录存在
            File parentDir = destFile.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                if (!parentDir.mkdirs()) {
                    return createErrorResponse("无法创建目标目录: " + parentDir.getAbsolutePath());
                }
            }

            try (InputStream in = new FileInputStream(sourceFile);
                 OutputStream out = new FileOutputStream(destFile)) {

                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }

                return createSuccessResponse("复制成功");
            } catch (IOException e) {
                return createErrorResponse("复制文件失败: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean copyFile(String sourcePath, String destPath) {
        try {
            String result = copyFileByPath(sourcePath, destPath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 列出目录文件 - 重构版本，接受目录路径而不是File对象，返回JSON格式
    @JavascriptInterface
    public String listDirectory(String dirPath) {
        return executeFileOperation(() -> {
            if (dirPath == null || dirPath.trim().isEmpty()) {
                return createErrorResponse("目录路径不能为空");
            }

            File directory = new File(dirPath);

            if (!directory.exists()) {
                return createErrorResponse("目录不存在: " + dirPath);
            }

            if (!directory.isDirectory()) {
                return createErrorResponse("指定路径不是目录: " + dirPath);
            }

            File[] files = directory.listFiles();

            if (files == null) {
                return createSuccessResponse("[]");
            }

            JSONArray fileList = new JSONArray();

            for (File file : files) {
                JSONObject fileInfo = new JSONObject();
                try {
                    fileInfo.put("name", file.getName());
                    fileInfo.put("isDirectory", file.isDirectory());
                    fileInfo.put("isFile", file.isFile());
                    fileInfo.put("size", file.length());
                    fileInfo.put("lastModified", file.lastModified());
                    fileInfo.put("canRead", file.canRead());
                    fileInfo.put("canWrite", file.canWrite());
                } catch (Exception e) {
                    // 忽略单个文件的JSON创建错误，继续处理其他文件
                    android.util.Log.w("FileUtil", "文件信息JSON创建失败: " + file.getName(), e);
                    continue;
                }
                fileList.put(fileInfo);
            }

            return createSuccessResponse(fileList.toString());
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public String listFiles(String dirPath) {
        return listDirectory(dirPath);
    }

    // 创建目录 - 重构版本，接受目录路径而不是File对象
    @JavascriptInterface
    public String createDirectoryByPath(String dirPath) {
        return executeFileOperation(() -> {
            if (dirPath == null || dirPath.trim().isEmpty()) {
                return createErrorResponse("目录路径不能为空");
            }

            File directory = new File(dirPath);

            try {
                if (directory.mkdirs()) {
                    return createSuccessResponse("目录创建成功");
                } else if (directory.exists()) {
                    return createSuccessResponse("目录已存在");
                } else {
                    return createErrorResponse("目录创建失败");
                }
            } catch (SecurityException e) {
                return createErrorResponse("目录创建失败，没有足够权限: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public boolean createDirectory(String dirPath) {
        try {
            String result = createDirectoryByPath(dirPath);
            JSONObject response = new JSONObject(result);
            return response.getBoolean("success");
        } catch (Exception e) {
            return false;
        }
    }

    // 关闭流
    private void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // TODO.
            }
        }
    }

    // 测试 - 重构版本，使用新的路径参数方法
    @JavascriptInterface
    public String testFileOperations(){
        return executeFileOperation(() -> {
            try {
                // 测试创建文件
                String filePath = createFile("internal", "test_file", ".txt");
                JSONObject createResponse = new JSONObject(filePath);
                if (!createResponse.getBoolean("success")) {
                    return createErrorResponse("文件创建测试失败: " + createResponse.getString("error"));
                }

                String testFilePath = createResponse.getString("data");

                // 测试写入
                String writeResult = writeTextToFile(testFilePath, "测试中文内容 Test English Content");
                JSONObject writeResponse = new JSONObject(writeResult);
                if (!writeResponse.getBoolean("success")) {
                    return createErrorResponse("写入测试失败: " + writeResponse.getString("error"));
                }

                // 测试读取
                String readResult = readTextFromFile(testFilePath);
                JSONObject readResponse = new JSONObject(readResult);
                if (!readResponse.getBoolean("success")) {
                    return createErrorResponse("读取测试失败: " + readResponse.getString("error"));
                }

                String content = readResponse.getString("data");

                // 测试追加
                String appendResult = appendTextToFile(testFilePath, "\n追加的内容");
                JSONObject appendResponse = new JSONObject(appendResult);
                if (!appendResponse.getBoolean("success")) {
                    return createErrorResponse("追加测试失败: " + appendResponse.getString("error"));
                }

                // 测试文件信息
                String sizeResult = getFileSizeByPath(testFilePath);
                JSONObject sizeResponse = new JSONObject(sizeResult);
                String fileSize = sizeResponse.getBoolean("success") ?
                    sizeResponse.getString("data") : "未知";

                String existsResult = fileExistsByPath(testFilePath);
                JSONObject existsResponse = new JSONObject(existsResult);
                String fileExists = existsResponse.getBoolean("success") ?
                    existsResponse.getString("data") : "false";

                // 清理
                String deleteResult = deleteFileByPath(testFilePath);
                JSONObject deleteResponse = new JSONObject(deleteResult);
                if (!deleteResponse.getBoolean("success")) {
                    return createErrorResponse("清理测试失败: " + deleteResponse.getString("error"));
                }

                return createSuccessResponse("所有测试通过! 文件大小: " + fileSize + "字节, 文件存在: " + fileExists);

            } catch (Exception e) {
                return createErrorResponse("测试过程中发生异常: " + e.getMessage());
            }
        });
    }

    // 兼容旧接口的方法
    @JavascriptInterface
    public String test(){
        return testFileOperations();
    }

    // ============ 辅助方法 ============

    /**
     * 执行文件操作，统一异常处理和锁定机制
     */
    private String executeFileOperation(Callable<String> operation) {
        fileLock.lock();
        try {
            return operation.call();
        } catch (Exception e) {
            return createErrorResponse("操作执行异常: " + e.getMessage());
        } finally {
            fileLock.unlock();
        }
    }

    /**
     * 创建成功响应
     */
    private String createSuccessResponse(String data) {
        try {
            JSONObject response = new JSONObject();
            response.put("success", true);
            response.put("data", data);
            response.put("timestamp", System.currentTimeMillis());
            return response.toString();
        } catch (Exception e) {
            return "{\"success\":false,\"error\":\"响应创建失败: " + escapeJson(e.getMessage()) + "\"}";
        }
    }

    /**
     * 创建错误响应
     */
    private String createErrorResponse(String error) {
        try {
            JSONObject response = new JSONObject();
            response.put("success", false);
            response.put("error", error);
            response.put("timestamp", System.currentTimeMillis());
            return response.toString();
        } catch (Exception e) {
            return "{\"success\":false,\"error\":\"错误响应创建失败\"}";
        }
    }

    /**
     * 转义JSON字符串中的特殊字符
     */
    private String escapeJson(String value) {
        if (value == null) {
            return "";
        }
        return value.replace("\\", "\\\\")
                   .replace("\"", "\\\"")
                   .replace("\b", "\\b")
                   .replace("\f", "\\f")
                   .replace("\n", "\\n")
                   .replace("\r", "\\r")
                   .replace("\t", "\\t");
    }

    /**
     * 获取存储信息
     */
    @JavascriptInterface
    public String getStorageInfo() {
        return executeFileOperation(() -> {
            try {
                JSONObject storageInfo = new JSONObject();

                // 内部存储信息
                if (appPrivateDir != null) {
                    JSONObject internal = new JSONObject();
                    try {
                        internal.put("totalSpace", appPrivateDir.getTotalSpace());
                        internal.put("freeSpace", appPrivateDir.getFreeSpace());
                        internal.put("usableSpace", appPrivateDir.getUsableSpace());
                        storageInfo.put("internal", internal);
                    } catch (Exception e) {
                        android.util.Log.w("FileUtil", "内部存储信息JSON创建失败", e);
                    }
                }

                // 外部存储信息
                if (appPublicDir != null) {
                    JSONObject external = new JSONObject();
                    try {
                        external.put("totalSpace", appPublicDir.getTotalSpace());
                        external.put("freeSpace", appPublicDir.getFreeSpace());
                        external.put("usableSpace", appPublicDir.getUsableSpace());
                        storageInfo.put("external", external);
                    } catch (Exception e) {
                        android.util.Log.w("FileUtil", "外部存储信息JSON创建失败", e);
                    }
                }

                return createSuccessResponse(storageInfo.toString());
            } catch (Exception e) {
                return createErrorResponse("获取存储信息失败: " + e.getMessage());
            }
        });
    }

    /**
     * 获取应用目录路径
     */
    @JavascriptInterface
    public String getAppDirectories() {
        return executeFileOperation(() -> {
            try {
                JSONObject directories = new JSONObject();

                if (appPrivateDir != null) {
                    try {
                        directories.put("internal", appPrivateDir.getAbsolutePath());
                    } catch (Exception e) {
                        android.util.Log.w("FileUtil", "内部目录信息JSON添加失败", e);
                    }
                }

                if (appPublicDir != null) {
                    try {
                        directories.put("external", appPublicDir.getAbsolutePath());
                    } catch (Exception e) {
                        android.util.Log.w("FileUtil", "外部目录信息JSON添加失败", e);
                    }
                }

                return createSuccessResponse(directories.toString());
            } catch (Exception e) {
                return createErrorResponse("获取目录路径失败: " + e.getMessage());
            }
        });
    }

    /**
     * 清理临时文件
     */
    @JavascriptInterface
    public String cleanupTempFiles() {
        return executeFileOperation(() -> {
            try {
                int cleanedCount = 0;

                // 清理内部临时文件
                if (appPrivateDir != null) {
                    cleanedCount += cleanupDirectory(appPrivateDir, "temp", "tmp");
                }

                // 清理外部临时文件
                if (appPublicDir != null) {
                    cleanedCount += cleanupDirectory(appPublicDir, "temp", "tmp");
                }

                return createSuccessResponse("清理完成，共删除 " + cleanedCount + " 个临时文件");
            } catch (Exception e) {
                return createErrorResponse("清理临时文件失败: " + e.getMessage());
            }
        });
    }

    /**
     * 辅助方法：清理指定类型的文件
     */
    private int cleanupDirectory(File directory, String... extensions) {
        int cleanedCount = 0;

        if (directory == null || !directory.exists() || !directory.isDirectory()) {
            return 0;
        }

        File[] files = directory.listFiles();
        if (files == null) {
            return 0;
        }

        long cutoffTime = System.currentTimeMillis() - (24 * 60 * 60 * 1000); // 24小时前

        for (File file : files) {
            if (file.isFile() && shouldCleanupFile(file, extensions, cutoffTime)) {
                try {
                    if (file.delete()) {
                        cleanedCount++;
                    }
                } catch (SecurityException e) {
                    // 忽略权限错误，继续处理其他文件
                }
            }
        }

        return cleanedCount;
    }

    /**
     * 判断文件是否应该被清理
     */
    private boolean shouldCleanupFile(File file, String[] extensions, long cutoffTime) {
        String fileName = file.getName().toLowerCase();

        // 检查扩展名
        if (extensions != null && extensions.length > 0) {
            boolean matchesExtension = false;
            for (String ext : extensions) {
                if (fileName.endsWith("." + ext.toLowerCase())) {
                    matchesExtension = true;
                    break;
                }
            }
            if (!matchesExtension) {
                return false;
            }
        }

        // 检查修改时间
        return file.lastModified() < cutoffTime;
    }
}
